﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Threading;
using MotionCS.Controller;
using MotionCS.Path;
using MotionCS.Helper;
using MotionCS.CameraVision;
using MotionCS.Config;
using MotionCS.Enumerate;
using MotionCS.Alarm;
using MotionCS.Helper;
namespace MotionCS.Module
{
    public class GrabDlp
    {
        /// <summary>
        /// 光源类型
        /// </summary>
        public GrabLightTypeE LightType;
        /// <summary>
        /// 光机触发
        /// </summary>
        public IDoBit DlpTrigger;
        /// <summary>
        /// 光机索引
        /// </summary>
        public DlpLocationE DlpIndex;
        /// <summary>
        /// 取像数量
        /// </summary>
        public int GrabNum;
    }

    public class GrabPoint
    {
        /// <summary>
        /// 地图索引
        /// </summary>
        public int Index = -1;
        /// <summary>
        /// X轴位置
        /// </summary>
        public float X { get; set; }
        /// <summary>
        /// Y轴位置
        /// </summary>
        public float Y { get; set; }
        /// <summary>
        /// 取像点位类型
        /// </summary>
        public GrabPositionTypeE PositionType = GrabPositionTypeE.Normal;
        /// <summary>
        /// 光源取像集合
        /// </summary>
        public List<GrabLightTypeE> grabLights;
        /// <summary>
        /// 光机取像集合
        /// </summary>
        public List<GrabDlp> grabDlps;
        /// <summary>
        /// 取像结束
        /// </summary>
        //public bool IsGrabEnd { get; set; }
    }

    public class CameraModule
    {
        private class GrabInfo
        {
            /// <summary>
            /// 工作模式
            /// </summary>
            public CameraWorkModeE WorkMode;
        }
        #region 流程枚举
        /// <summary>
        /// 点拍状态
        /// </summary>
        public enum PointStepE
        {
            /// <summary>
            /// 等待
            /// </summary>
            GrabNone,
            /// <summary>
            /// 初始
            /// </summary>
            GrabInit,
            /// <summary>
            /// 就绪
            /// </summary>
            GrabReady,
            /// <summary>
            /// 运动到取像点
            /// </summary>
            GrabGoto,
            /// <summary>
            /// 触发
            /// </summary>
            Grabbing,
            /// <summary>
            /// 取像
            /// </summary>
            GrabWait,
            /// <summary>
            /// 光机触发
            /// </summary>
            GrabDlpGrabbing,
            /// <summary>
            /// 光机等待
            /// </summary>
            GrabDlpWait,
            /// <summary>
            /// 完成
            /// </summary>
            GrabFinish,
            /// <summary>
            /// 退出
            /// </summary>
            GrabExit
        }
        /// <summary>
        /// 复位状态机
        /// </summary>
        public enum ResetStepE
        {
            /// <summary>
            /// 初始
            /// </summary>
            Init,
            /// <summary>
            /// 驱动器复位
            /// </summary>
            Driver,
            /// <summary>
            /// 回零
            /// </summary>
            GoHome,
            /// <summary>
            /// 回零成功
            /// </summary>
            WaitHome,
            /// <summary>
            /// 运动到基点
            /// </summary>
            GoBase,
            /// <summary>
            /// 等待运动到基点
            /// </summary>
            WaitBase,
            /// <summary>
            /// 成功
            /// </summary>
            Success,
            /// <summary>
            /// 失败
            /// </summary>
            Failed
        }
        #endregion
        #region 模组属性
        /// <summary>
        /// 模组键值
        /// </summary>
        public int ModuleKey { get => config.ModuleKey; }
        /// <summary>
        /// 模组名称
        /// </summary>
        public string ModuleName { get => config.Name; }
        /// <summary>
        /// 步距X
        /// </summary>
        public float StepX { get => config.Calibration.StepX; }
        /// <summary>
        /// 步距Y
        /// </summary>
        public float StepY { get => config.Calibration.StepY; }
        /// <summary>
        /// 是否启用
        /// </summary>
        public bool isEnable = false;
        public bool IsEnable { get => isEnable; }
        /// <summary>
        /// 是否输出日志
        /// </summary>
        private bool isLogout;
        public bool IsLogOut { get => isLogout; set { isLogout = value; } }
        #endregion
        #region 硬件属性
        /// <summary>
        /// 模组配置
        /// </summary>
        private CameraModuleConfig config;
        /// <summary>
        /// 相机
        /// </summary>
        private ICamera camera;
        public ICamera Camera
        {
            get => camera;
        }
        /// <summary>
        /// X轴
        /// </summary>
        private IAxis axisX;
        public IAxis AxisX { get => axisX; }
        /// <summary>
        /// Y轴
        /// </summary>
        private IAxis axisY;
        public IAxis AxisY { get => axisY; }
        /// <summary>
        /// 频闪红
        /// </summary>
        private IDoBit strobeR;
        /// <summary>
        /// 频闪绿
        /// </summary>
        private IDoBit strobeG;
        /// <summary>
        /// 频闪蓝
        /// </summary>
        private IDoBit strobeB;
        /// <summary>
        /// 频闪白
        /// </summary>
        private IDoBit strobeW;
        /// <summary>
        /// RGBW相机触发
        /// </summary>
        private IDoBit camTrigger;
        /// <summary>
        /// 左光机相机触发
        /// </summary>
        private IDoBit camLeftDlp;
        /// <summary>
        /// 右光机相机触发
        /// </summary>
        private IDoBit camRightDlp;
        /// <summary>
        /// 前光机相机触发
        /// </summary>
        private IDoBit camFrontDlp;
        /// <summary>
        /// 后光机相机触发
        /// </summary>
        private IDoBit camBackDlp;
        #endregion
        #region 流程属性

        private AlarmDetect alarmDetect = new AlarmDetect();
        /// <summary>
        /// 主任务状态机
        /// </summary>
        private ModuleTaskStateE runTaskStep;
        /// <summary>
        /// 主任务线程
        /// </summary>
        private Thread MainThread;
        /// <summary>
        /// 主任务循环
        /// </summary>
        private bool MainLoop = false;
        /// <summary>
        /// 产品数据
        /// </summary>
        private ProductData productData;
        /// <summary>
        /// 地图集合
        /// </summary>
        private List<MapPath> mapItems = new List<MapPath>();
        /// <summary>
        /// 基础点位
        /// </summary>
        private Position basePoint;
        /// <summary>
        /// 点拍点位
        /// </summary>
        private MapPoint mapPoint;
        /// <summary>
        /// 飞拍点位
        /// </summary>
        private MapFlying mapFlying;
        /// <summary>
        /// 拍照点位字典
        /// </summary>
        private ConcurrentDictionary<ConveyorModuleE, List<GrabPoint>> grabPointsDic;
        /// <summary>
        /// 取像点集合
        /// </summary>
        private List<GrabPoint> grabPoints = new List<GrabPoint>();
        /// <summary>
        /// 取像点位索引
        /// </summary>
        private Int32 grabIndex;
        /// <summary>
        /// 取像光源索引
        /// </summary>
        private Int32 lightIndex;
        /// <summary>
        /// 取像光机索引
        /// </summary>
        private Int32 dlpIndex;
        /// <summary>
        /// 图像计数
        /// </summary>
        private Int32 ImageCount;
        /// <summary>
        /// 点拍状态机
        /// </summary>
        private PointStepE pointStep;
        /// <summary>
        /// 运行标识
        /// </summary>
        private bool IsReseting;
        /// <summary>
        /// 曝光结束
        /// </summary>
        //private bool exposureEnd;
        /// <summary>
        /// 重拍图像
        /// </summary>
        private ConcurrentQueue<Int32> remakeImage;
        /// <summary>
        /// 上次时间
        /// </summary>
        private DateTime lastTime;
        /// <summary>
        /// 检测超时时长
        /// </summary>
        private int detectTimeOut;
        /// <summary>
        /// 丢帧超时
        /// </summary>
        public Int32 LoseFrameTimeout = 100;
        /// <summary>
        /// 复位状态机
        /// </summary>
        private ResetStepE resetStep;
        /// <summary>
        /// 复位开始时间
        /// </summary>
        private DateTime resetTime;
        /// <summary>
        /// 整版耗时
        /// </summary>
        private Stopwatch grabAllWatch;
        /// <summary>
        /// 整版耗时
        /// </summary>
        private Stopwatch grabWatch;
        /// <summary>
        /// 整版耗时
        /// </summary>
        private Stopwatch MoveWatch;
        /// <summary>
        /// 测试sleep时间
        /// </summary>
        private Stopwatch SleepTime = new Stopwatch();
        /// <summary>
        /// 整版耗时
        /// </summary>
        private Stopwatch GarbWaitWatch;

        /// <summary>
        /// 取像互斥锁
        /// </summary>
        //private static Mutex grabMutex = new Mutex();
        /// <summary>
        /// 轨道模组
        /// </summary>
        private ConcurrentDictionary<int, GrabInfo> conveyors = new ConcurrentDictionary<int, GrabInfo>();
        /// <summary>
        /// 是否收到图像帧
        /// </summary>
        private bool IsGrabImageEnd = false;
        /// <summary>
        /// 取像轮次
        /// </summary>
        private UInt32 GrabRoundIndex = 0; 
        #endregion
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="name"></param>
        public CameraModule(CameraModuleConfig moduleConfig)
        {
            config = moduleConfig;
            if (InitHardwareModule() != 0)
            {
                return;
            }

            InitAlarmModule();

            grabPointsDic = new ConcurrentDictionary<ConveyorModuleE, List<GrabPoint>>();
            grabPointsDic.TryAdd(ConveyorModuleE.Front, new List<GrabPoint>());
            grabPointsDic.TryAdd(ConveyorModuleE.Back, new List<GrabPoint>());
            float x = config.ConveyorFront.Direction == (int)LineDirectionE.Left ? config.Calibration.LBaseX : config.Calibration.RBaseX;
            float y = config.ConveyorFront.Direction == (int)LineDirectionE.Left ? config.Calibration.LBaseY : config.Calibration.RBaseY;
            basePoint = new Position(x, y);

            DataCenter.Instance.CameraResetInit(config.ModuleKey);

            isEnable = true;
            MainLoop = true;

            MainThread = new Thread(new ThreadStart(MainTaskFunction));
            MainThread.IsBackground = true;
            MainThread.Priority = ThreadPriority.Highest;
            MainThread.Start();

            //CancellationTokenSource CT_MainTask = new CancellationTokenSource();

            //Task.Run(MainTaskFunction, CT_MainTask.Token);


            runTaskStep = ModuleTaskStateE.Idle;
            remakeImage = new ConcurrentQueue<int>();
            pointStep = PointStepE.GrabNone;
            grabAllWatch = new Stopwatch();
            grabWatch = new Stopwatch();
            MoveWatch = new Stopwatch();
            GarbWaitWatch = new Stopwatch();
        }
        /// <summary>
        /// 初始化硬件模组
        /// </summary>
        private int InitHardwareModule()
        {
            axisX = MotionDevice.Instance.GetAxis(config.AxisX);
            if (AxisX == null)
            {
                Logout($"X轴初始化失败.");
                return -1;
            }
            axisY = MotionDevice.Instance.GetAxis(config.AxisY);
            if ( AxisY == null)
            {
                Logout($"Y轴初始化失败.");
                return -1;
            }

            strobeR = MotionDevice.Instance.DoBit(config.StrobeR);
            strobeG = MotionDevice.Instance.DoBit(config.StrobeG);
            strobeB = MotionDevice.Instance.DoBit(config.StrobeB);
            strobeW = MotionDevice.Instance.DoBit(config.StrobeW);
            if (strobeR == null || strobeG == null || strobeB == null || strobeW == null)
            {
                Logout($"相机光源触发IO未配置.");
                return -1;
            }

            camTrigger = MotionDevice.Instance.DoBit(config.CamTrigger);
            camLeftDlp = MotionDevice.Instance.DoBit(config.CamLeftDlp);
            if (config.LeftDlpGrabNum > 0 && camLeftDlp == null)
            {
                Logout($"左光机启用，触发IO未配置.");
                return -1;
            }
            camRightDlp = MotionDevice.Instance.DoBit(config.CamRightDlp);
            if (config.RightDlpGrabNum > 0 && camRightDlp == null)
            {
                Logout($"右光机启用，触发IO未配置.");
                return -1;
            }
            camFrontDlp = MotionDevice.Instance.DoBit(config.CamFrontDlp);
            if (config.FrontDlpGrabNum > 0 && camFrontDlp == null)
            {
                Logout($"前光机启用，触发IO未配置.");
                return -1;
            }
            camBackDlp = MotionDevice.Instance.DoBit(config.CamBackDlp);
            if (config.BackDlpGrabNum > 0 && camBackDlp == null)
            {
                Logout($"后光机启用，触发IO未配置.");
                return -1;
            }

            camera = VisionDevice.Instance.GetCamera(config.CameraType, config.CameraName);
            if (camera == null)
            {
                Logout($"相机检索失败.");
                return -1;
            }
            camera.LogoutCallBack = Logout;
            camera.ImageCallBack = config.ImageCallback;
            camera.ExposureCallBack = ExposureEndFunction;
            camera.GrabEndCallback = GrabEndFunction;
            if (camera.OpenDevice())
            {
                camera.StartGrab();
            }
            else
            {
                Logout($"相机打开失败.");
                return -1;
            }

            if (config.ConveyorFront.Enable == 1)
            {
                mapItems.Add(new MapPath(new MapConfi()
                {
                    Module = ConveyorModuleE.Front,
                    LineDirection = config.ConveyorFront.Direction,
                    //WAxisFixed = config.ConveyorFront.WAxisFixed,
                    limitP = new Position(AxisX.Config.FsLimit, AxisY.Config.FsLimit),
                    limitN = new Position(AxisX.Config.RsLimit, AxisY.Config.RsLimit),
                    DirectionX = AxisX.Config.MoveDir,
                    DirectionY = AxisY.Config.MoveDir,
                    StepX = config.Calibration.StepX,
                    StepY = config.Calibration.StepY,
                    StartX = config.ConveyorFront.Direction == (int)LineDirectionE.Left ? config.Calibration.FrontLStartX : config.Calibration.FrontRStartX,
                    StartY = config.ConveyorFront.Direction == (int)LineDirectionE.Left ? config.Calibration.FrontLStartY : config.Calibration.FrontRStartY,
                }));
            }

            if (config.ConveyorBack.Enable == 1)
            {
                mapItems.Add(new MapPath(new MapConfi()
                {
                    Module = ConveyorModuleE.Back,
                    LineDirection = config.ConveyorBack.Direction,
                    WAxisFixed = config.ConveyorBack.WAxisFixed,
                    limitP = new Position(AxisX.Config.FsLimit, AxisY.Config.FsLimit),
                    limitN = new Position(AxisX.Config.RsLimit, AxisY.Config.RsLimit),
                    DirectionX = AxisX.Config.MoveDir,
                    DirectionY = AxisY.Config.MoveDir,
                    StepX = config.Calibration.StepX,
                    StepY = config.Calibration.StepY,
                    StartX = config.ConveyorBack.Direction == (int)LineDirectionE.Left ? config.Calibration.BackLStartX : config.Calibration.BackRStartX,
                    StartY = config.ConveyorBack.Direction == (int)LineDirectionE.Left ? config.Calibration.BackLStartY : config.Calibration.BackRStartY,
                }));
            }

            Logout($"模组初始化完成.");

            return 0;
        }
        /// <summary>
        /// 初始化报警模组
        /// </summary>
        private void InitAlarmModule()
        {
            alarmDetect.LogoutCallback = Logout;
            InitAxisAlarm(axisX, ErrorCodeE.CamAxisX);
            InitAxisAlarm(axisY, ErrorCodeE.CamAxisY);
            InitCameraAlarm(ErrorCodeE.CamOnline);
            InitTimeoutAlarm(ErrorCodeE.CamGrabTimeout);
        }
        /// <summary>
        /// 初始化轴报警
        /// </summary>
        /// <param name="axis"></param>
        private void InitAxisAlarm(IAxis axis, ErrorCodeE code)
        {
            var alarm = new AlarmItem();
            alarm.ErrorID = (int)(code + config.ModuleKey);
            alarm.Message = $"{axis.Config.Name}";
            alarm.Level = AlarmLevelE.Error;
            alarm.IsAlarmCallback = new Func<bool>(() =>
            {
                bool isAlm = false;
                MotorStatus status = axis.GetStatus();
                if (status != null)
                {
                    isAlm = status.ElNegLimit || status.ElNegLimit || status.EmgStop || status.ServoAlarm;
                    if (isAlm)
                    {
                        alarm.Message = $"{axis.Config.Name}" + (status.ElPosLimit ? "正限位" : "")
                            + (status.ElNegLimit ? "负限位" : "") + (status.ServoAlarm ? "伺服异常" : "");
                    }
                }

                return isAlm;
            });
            alarmDetect.AlarmItems.Add(alarm);
        }
        /// <summary>
        /// 初始化相机连接报警
        /// </summary>
        private void InitCameraAlarm(ErrorCodeE code)
        {
            var alarm = new AlarmItem();
            alarm.ErrorID = (int)code;
            alarm.Message = $"{config.Name}连接异常";
            alarm.Level = AlarmLevelE.Error;
            alarm.IsAlarmCallback = new Func<bool>(() =>
            {
                return !camera.IsConnected;
            });
            alarm.AlarmEndedCallback = new Action(() =>
            {
                if (runTaskStep == ModuleTaskStateE.Error)
                {
                    runTaskStep = ModuleTaskStateE.Idle;
                }
            });
            alarmDetect.AlarmItems.Add(alarm);
        }
        /// <summary>
        /// 初始化取像超时报警
        /// </summary>
        private void InitTimeoutAlarm(ErrorCodeE code)
        {
            var alarm = new AlarmItem();
            alarm.ErrorID = (int)code;
            alarm.Message = $"{config.Name}取像超时";
            alarm.Level = AlarmLevelE.Error;
            alarm.IsAlarmCallback = new Func<bool>(() =>
            {
                return detectTimeOut == 1;
            });
            alarmDetect.AlarmItems.Add(alarm);
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            MainLoop = false;
            camera?.Dispose();
        }
        /// <summary>
        /// 获取轨道地图
        /// </summary>
        /// <param name="module"></param>
        /// <returns></returns>
        private MapPath GetMapPath(ConveyorModuleE module)
        {
            return mapItems.Find(p => p.Module == module);
        }
        /// <summary>
        /// 曝光结束
        /// </summary>
        public void ExposureEndFunction(string sn)
        {
            if (pointStep == PointStepE.GrabWait || pointStep == PointStepE.Grabbing)
            {
                if (CameraGrabConfig.GlobalGrabMode != CameraGrabConfig.GrabModelEnum.Optimization)
                {
                    CameraGrabConfig.ExposureSemaphore.Release();
                }
                if (grabPoints.Count > grabIndex)
                {
                    Logout($"相机取像曝光,取像点:{grabIndex},图像:{lightIndex}");
                }
            }
            else if (pointStep == PointStepE.GrabDlpWait || pointStep == PointStepE.GrabDlpGrabbing)
            {
                if (ImageCount++ == grabPoints[grabIndex].grabDlps[dlpIndex].GrabNum)
                { 
                    if (CameraGrabConfig.GlobalGrabMode != CameraGrabConfig.GrabModelEnum.Optimization)
                    {
                        CameraGrabConfig.ExposureSemaphore.Release();
                    }
                    if (grabPoints.Count > grabIndex)
                    {
                        Logout($"光机取像曝光,取像点:{grabIndex},图像:{dlpIndex}");
                    }
                }
            }
        }
        /// <summary>
        /// 抓拍结束
        /// </summary>
        public void GrabEndFunction(string sn)
        {
            Logout($"相机取像完成,取像点:{grabIndex},收到图像:{lightIndex},耗时{grabWatch.ElapsedMilliseconds}ms");
            //获取一次拍照锁
            CameraGrabConfig.GrabSemaphore.Release();
            IsGrabImageEnd = true;
        }
        /// <summary>
        /// 重拍帧索引添加到队列
        /// </summary>
        /// <param name="idx"></param>
        public void RemakeEnqueue(Int32 idx)
        {
            remakeImage.Enqueue(idx);
        }
        /// <summary>
        /// 重拍帧队列清空
        /// </summary>
        private void RemakeClear()
        {
            while (!remakeImage.IsEmpty)
            {
                remakeImage.TryDequeue(out int re);
            }

            camera.ClearGrabInfo();
        }
        /// <summary>
        /// 相机触发打开
        /// </summary>
        private void CameraTriggerOn(FrameInfo info)
        {
            IsGrabImageEnd = false;
            if (camTrigger == null)
            {
                camera.SoftwareTrigger(info);
            }
            else
            {
                camera.SetHardTriggerInfo(info);
                grabWatch.Restart();
                camTrigger.TurnOn();
            }
        }
        /// <summary>
        /// 相机触发关闭
        /// </summary>
        /// <param name="info"></param>
        private void CameraTriggerOff()
        {
            if (camTrigger != null)
            {
                camTrigger.TurnOff();
            }
        }
        /// <summary>
        /// 日志输出
        /// </summary>
        /// <param name="loginfo"></param>
        private void Logout(string loginfo)
        {
            Logger.Logout($"{config.Name}：" + loginfo);
        }
        /// <summary>
        /// 复位初始化
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepInit()
        {
            detectTimeOut = 0;
            
            DataCenter.Instance.SetCameraResetProcess(config.ModuleKey);
            return ResetStepE.GoHome;
        }
        /// <summary>
        /// 复位驱动器
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepDriver()
        {
            AxisX.SevonEnable();
            AxisY.SevonEnable();
            AxisX.ResetEnable();
            AxisY.ResetEnable();

            TimeSpan span = DateTime.Now - resetTime;
            if (span.TotalMilliseconds >= 100
                && !AxisX.IsAlarm() && !AxisY.IsAlarm())
            {
                AxisX.ResetDisable();
                AxisY.ResetDisable();
                Logout("复位伺服驱动器结束.");
                return ResetStepE.GoHome;
            }
            return ResetStepE.Driver;
        }
        /// <summary>
        /// 运动到原点
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepGoHome()
        {
            if (AxisX.IsCheckDone() && AxisY.IsCheckDone())
            {

                AxisX.MoveHome();
                AxisY.MoveHome();
                Logout($"X和Y轴开始回零.");
                return ResetStepE.WaitHome;
               
            }

            return ResetStepE.GoHome;
        }
        /// <summary>
        /// 等待运动到原点
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepWaitHome()
        {
            if (AxisX.IsCheckDone() && AxisX.IsInp()
                && AxisY.IsCheckDone() && AxisY.IsInp())
            {
                if (!AxisX.IsElFwdLimit() && !AxisY.IsElRevLimit())
                {
                    AxisX.SetEncoderUnit(0.0f);
                    AxisY.SetEncoderUnit(0.0f);
                    AxisX.SetAutoSpeed();
                    AxisY.SetAutoSpeed();
                    Logout($"复位X轴和Y轴回零点成功.");
                    return ResetStepE.GoBase;
                }

                if (AxisX.IsElFwdLimit())
                {
                    Logout("复位X轴撞硬件限位,相对运动到-100.");
                    AxisX.MoveRel(-100);
                }

                if (AxisY.IsElRevLimit())
                {
                    Logout("复位Y轴撞硬件限位,相对运动到100.");
                    AxisY.MoveRel(100);
                }

                return ResetStepE.GoHome;
            }
            else
            {
                return ResetStepE.WaitHome;
            }
        }
        /// <summary>
        /// 运动到加载点
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepGoBase()
        {
            AxisX.MoveAbs(basePoint.x);
            AxisY.MoveAbs(basePoint.y);

            Logout($"复位运动到基点:({basePoint.x},{basePoint.y})");
            return ResetStepE.WaitBase;
        }
        /// <summary>
        /// 等待运动到加载点
        /// </summary>
        /// <returns></returns>
        private ResetStepE ResetStepWaitBase()
        {
            if (AxisX.IsCheckDone() && AxisX.IsInp()
                && AxisY.IsCheckDone() && AxisY.IsInp())
            {
                Logout("复位X轴Y轴结束.");
                DataCenter.Instance.SetCameraResetFinish(config.ModuleKey);
                return ResetStepE.Success;
            }
            else
            {
                return ResetStepE.WaitBase;
            }
        }
        /// <summary>
        /// 复位功能
        /// </summary>
        public ModuleTaskStateE ResetFunction()
        {
            DateTime dateTime = DateTime.Now;
            TimeSpan span = dateTime - resetTime;
            if ((int)span.TotalSeconds >= 60
                && (resetStep != ResetStepE.Success)
                && (resetStep != ResetStepE.Failed))
            {
                resetTime = dateTime;
                resetStep = ResetStepE.Failed;
                Logout("复位超时.");
                //DataCenter.Instance.SetCameraResetFinish(config.ModuleKey, false);
            }

            switch (resetStep)
            {
                case ResetStepE.Init:
                    resetStep = ResetStepInit();
                    break;
                case ResetStepE.Driver:
                    //resetStep = ResetStepDriver();
                    break;
                case ResetStepE.GoHome:
                    resetStep = ResetStepGoHome();
                    break;
                case ResetStepE.WaitHome:
                    resetStep = ResetStepWaitHome();
                    break;
                case ResetStepE.GoBase:
                    resetStep = ResetStepGoBase();
                    break;
                case ResetStepE.WaitBase:
                    resetStep = ResetStepWaitBase();
                    break;
                case ResetStepE.Success:

                    break;
                default:
                    break;
            }

            if (resetStep == ResetStepE.Success)
            {
                if (conveyors.ToList().Exists(itm => itm.Value.WorkMode == CameraWorkModeE.Detect))
                {
                    return ModuleTaskStateE.Running;
                }
                else
                {
                
                    return ModuleTaskStateE.Idle;
                }
            }
            else if (resetStep == ResetStepE.Failed)
            {
                return ModuleTaskStateE.Error;
            }
            else
            {
                return ModuleTaskStateE.Resetting;
            }
        }
        /// <summary>
        /// 复位启动
        /// </summary>
        public int ResetStart()
        {
            if (runTaskStep == ModuleTaskStateE.Resetting)
            {
                Logout($"正在复位中");
                return 0;
            }

            if (runTaskStep != ModuleTaskStateE.Idle 
                && runTaskStep != ModuleTaskStateE.Error)
            {
                Logout($"复位失败，当前状态:{runTaskStep}");
                return -1;
            }
            else
            {
                DataCenter.Instance.SetCameraResetProcess(config.ModuleKey);
                IsReseting = true;
                Logout($"收到复位操作");
                return 0;
            }
        }
        /// <summary>
        /// 设置复位完成
        /// </summary>
        /// <returns></returns>
        public int SetResetFinish()
        {
            DataCenter.Instance.SetCameraResetFinish(config.ModuleKey);
            return 0;
        }

        /// <summary>
        /// 光源控制打开
        /// </summary>
        /// <param name="lightTyoe"></param>
        public void TurnOnLightByGrabType(GrabLightTypeE lightTyoe)
        {
            switch (lightTyoe)
            {
                case GrabLightTypeE.RGBLight:
                    Parallel.Invoke(strobeR.TurnOn, strobeG.TurnOn, strobeB.TurnOn);
                    break;
                case GrabLightTypeE.WhiteLight:
                    strobeW.TurnOn();
                    break;
                case GrabLightTypeE.RGBAndWhite:
                    Parallel.Invoke(strobeR.TurnOn, strobeG.TurnOn, strobeB.TurnOn, strobeW.TurnOn);
                    break;
                case GrabLightTypeE.RedLight:
                    strobeR.TurnOn();
                    break;
                case GrabLightTypeE.GreenLight:
                    strobeG.TurnOn();
                    break;
                case GrabLightTypeE.BlueLight:
                    strobeB.TurnOn();
                    break;
                case GrabLightTypeE.None:
                    TurnOffLightByGrabType(GrabLightTypeE.RGBAndWhite);
                    break;
                default:
                    break;
            }
            ThreadHelper.Delay(10);
        }
        /// <summary>
        /// 光源控制关闭
        /// </summary>
        /// <param name="lightTyoe"></param>
        public void TurnOffLightByGrabType(GrabLightTypeE lightTyoe)
        {

            switch (lightTyoe)
            {
                case GrabLightTypeE.RGBLight:
                    Parallel.Invoke(strobeR.TurnOff, strobeG.TurnOff, strobeB.TurnOff);
                    break;
                case GrabLightTypeE.WhiteLight:
                    strobeW.TurnOff();
                    break;
                case GrabLightTypeE.RGBAndWhite:
                    Parallel.Invoke(strobeR.TurnOff, strobeG.TurnOff, strobeB.TurnOff, strobeW.TurnOff);
                    break;
                case GrabLightTypeE.RedLight:
                    strobeR.TurnOff();
                    break;
                case GrabLightTypeE.GreenLight:
                    strobeG.TurnOff();
                    break;
                case GrabLightTypeE.BlueLight:
                    strobeB.TurnOff();
                   
                   
   
                    break;

                case GrabLightTypeE.DLPLight:
                    if (config.LeftDlpGrabNum > 0)
                        camLeftDlp.TurnOff();
                    if (config.RightDlpGrabNum > 0)
                        camRightDlp.TurnOff();
                    if (config.FrontDlpGrabNum > 0)
                        camFrontDlp.TurnOff();
                    if (config.BackDlpGrabNum > 0)
                        camBackDlp.TurnOff();

                    break;
                case GrabLightTypeE.None:
                    TurnOffLightByGrabType(GrabLightTypeE.RGBAndWhite);
            
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 点拍光源类型
        /// </summary>
        /// <param name="lightType"></param>
        /// <returns></returns>
        private List<GrabLightTypeE> PointGrablightType(GrabLightTypeE lightType)
        {
            List<GrabLightTypeE> grabLights = new List<GrabLightTypeE>();

            switch (lightType)
            {
                case GrabLightTypeE.RGBLight:
                    if (config.CameraColor == CameraColorE.Rgb)
                    {
                        grabLights.Add(GrabLightTypeE.RGBLight);
                    }
                    else
                    {
                        grabLights.Add(GrabLightTypeE.RedLight);
                        grabLights.Add(GrabLightTypeE.GreenLight);
                        grabLights.Add(GrabLightTypeE.BlueLight);
                    }
                    break;
                case GrabLightTypeE.RGBAndWhite:
                    if (config.CameraColor == CameraColorE.Rgb)
                    {
                        grabLights.Add(GrabLightTypeE.RGBLight);
                        grabLights.Add(GrabLightTypeE.WhiteLight);
                    }
                    else
                    {
                        grabLights.Add(GrabLightTypeE.RedLight);
                        grabLights.Add(GrabLightTypeE.GreenLight);
                        grabLights.Add(GrabLightTypeE.BlueLight);
                        grabLights.Add(GrabLightTypeE.WhiteLight);
                    }
                    break;
                case GrabLightTypeE.RGBAndDLP:
                    if (config.CameraColor == CameraColorE.Rgb)
                    {
                        grabLights.Add(GrabLightTypeE.RGBLight);
                    }
                    else
                    {
                        grabLights.Add(GrabLightTypeE.RedLight);
                        grabLights.Add(GrabLightTypeE.GreenLight);
                        grabLights.Add(GrabLightTypeE.BlueLight);
                    }
                    break;
                case GrabLightTypeE.RGBAndWhiteAndDLP:
                    if (config.CameraColor == CameraColorE.Rgb)
                    {
                        grabLights.Add(GrabLightTypeE.RGBLight);
                        grabLights.Add(GrabLightTypeE.WhiteLight);
                    }
                    else
                    {
                        grabLights.Add(GrabLightTypeE.RedLight);
                        grabLights.Add(GrabLightTypeE.GreenLight);
                        grabLights.Add(GrabLightTypeE.BlueLight);
                        grabLights.Add(GrabLightTypeE.WhiteLight);
                    }
                    break;
                case GrabLightTypeE.WhiteAndDLP:
                    grabLights.Add(GrabLightTypeE.WhiteLight);
                    break;
                case GrabLightTypeE.DLPLight:
                    break;
                default:
                    grabLights.Add(lightType);
                    break;
            }

            return grabLights;
        }

        private List<GrabDlp> PointGrabDlp(GrabLightTypeE lightType)
        {
            List<GrabDlp> grabDlps = new List<GrabDlp>();

            switch (lightType)
            {
                case GrabLightTypeE.RGBAndDLP:
                case GrabLightTypeE.RGBAndWhiteAndDLP:
                case GrabLightTypeE.WhiteAndDLP:
                case GrabLightTypeE.DLPLight:
                    if (config.LeftDlpGrabNum > 0)
                    {
                        grabDlps.Add(new GrabDlp() 
                        { 
                            LightType = GrabLightTypeE.DLPLight,
                            DlpTrigger = camLeftDlp, 
                            DlpIndex = DlpLocationE.Left,
                            GrabNum = config.LeftDlpGrabNum,
                        });
                    }
                    if (config.FrontDlpGrabNum > 0)
                    {
                        grabDlps.Add(new GrabDlp() 
                        { 
                            LightType = GrabLightTypeE.DLPLight,
                            DlpTrigger = camFrontDlp,
                            DlpIndex = DlpLocationE.Front,
                            GrabNum = config.FrontDlpGrabNum
                        });
                    }
                    if (config.RightDlpGrabNum > 0)
                    {
                        grabDlps.Add(new GrabDlp() 
                        { 
                            LightType = GrabLightTypeE.DLPLight,
                            DlpTrigger = camRightDlp, 
                            DlpIndex = DlpLocationE.Right, 
                            GrabNum = config.RightDlpGrabNum 
                        });
                    }
                    if (config.BackDlpGrabNum > 0)
                    {
                        grabDlps.Add(new GrabDlp() 
                        { 
                            LightType = GrabLightTypeE.DLPLight,
                            DlpTrigger = camBackDlp, 
                            DlpIndex = DlpLocationE.Back, 
                            GrabNum = config.BackDlpGrabNum 
                        });
                    }
                    break;
                default:
                    break;
            }

            return grabDlps;
        }
        /// <summary>
        /// 设置主任务状态
        /// </summary>
        /// <param name="state"></param>
        private void SetMainTaskState(ModuleTaskStateE state)
        {
            if (runTaskStep == ModuleTaskStateE.Running
                && state == ModuleTaskStateE.Error)
            {
                PointStepExit();
            }

            if (state != runTaskStep)
            {
                Logout($"{runTaskStep} ==> {state}");
                runTaskStep = state;
            }
        }
        /// <summary>
        /// 初始状态
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepGrabInit()
        {
            Logout($"取像初始化");

            TurnOffLightByGrabType(GrabLightTypeE.RGBAndWhite);
            TurnOffLightByGrabType(GrabLightTypeE.DLPLight);
            AxisX.SetAutoSpeed();
            AxisY.SetAutoSpeed();
            //grabAllWatch.Restart();

            CameraGrabConfig.ExposureSemaphore = new Semaphore(0, 1);
            CameraGrabConfig.GrabSemaphore = new Semaphore(8, 8);

            return PointStepE.GrabReady;
        }
        /// <summary>
        /// 启动状态
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepGrabReady()
        {
            if (DataCenter.Instance.CameraTryDequeue(config.ModuleKey, out ProductData upData))
            {
                productData = upData;
            }
            else
            {
                productData = null;
            }

            if (productData != null)
            {
                RemakeClear();
                grabIndex = 0;
                detectTimeOut = 0;
                lastTime = DateTime.Now;
                IsGrabImageEnd = true;
                productData.Uuid = DateTime.Now.ToString("yyyyMMddHHmmssfff");
                Logout($"收到{Enum.GetName(typeof(ConveyorModuleE),productData.Station)}轨道产品:{productData.QrCode},启动取像.");
                grabPoints = grabPointsDic[(ConveyorModuleE)productData.Station];
                return PointStepE.GrabGoto;
            }
            else
            {
                return PointStepE.GrabReady;
            }
        }

        //bool g_bImageEnd = false;
        //bool g_bRunOK = false;

        /// <summary>
        /// 就绪状态
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepGrabGoto()
        {
            if (grabIndex < grabPoints.Count)
            {
                //exposureEnd = false;
                lastTime = DateTime.Now;
                MoveWatch.Restart();
                AxisX.MoveAbs(grabPoints[grabIndex].X);
                AxisY.MoveAbs(grabPoints[grabIndex].Y);
                lightIndex = 0;
                Logout($"拍照平台移动到拍照点({grabPoints[grabIndex].X},{grabPoints[grabIndex].Y})");
                if(grabIndex == 0) grabAllWatch.Restart();
                return PointStepE.Grabbing;
            }
            else
            {
                Logout($"通知{Enum.GetName(typeof(ConveyorModuleE), productData.Station)}轨道取像完成");
                DataCenter.Instance.ConveyorEnqueue(productData.Station, new ProductData()
                {
                    Uuid = productData.Uuid,
                    QrCode = productData.QrCode,
                    Station = config.ModuleKey
                });
                Logout($"整板取像耗时:{grabAllWatch.ElapsedMilliseconds}");
                grabAllWatch.Stop();
                // 运动到零点附近再回零
                AxisX.MoveAbs(basePoint.x);
                AxisY.MoveAbs(basePoint.y);
                lastTime = DateTime.Now;
                return PointStepE.GrabFinish;
            }
        }
        /// <summary>
        /// 触发拍照
        /// </summary>
        /// <returns></returns>
        /// 
      
        private PointStepE PointStepGrabbing()
        {
            if(AxisX.IsCheckDone() && AxisY.IsCheckDone() && AxisX.IsInp() && AxisY.IsInp())
            {
                //防止抖动
                if (lightIndex == 0)
                {
                    ThreadHelper.Delay(CameraGrabConfig.WaitMoveStopTime, true);
                    Logout($"收到X,Y运动完成，移动耗时：{MoveWatch.ElapsedMilliseconds}ms");
                    GarbWaitWatch.Restart();
                }

                //获取一次拍照锁
                CameraGrabConfig.GrabSemaphore.WaitOne();
                //grabMutex.WaitOne();
                Logout($"触发相机取像，点位:{grabIndex},图像:{lightIndex},光源:{grabPoints[grabIndex].grabLights[lightIndex]},耗时：{GarbWaitWatch.ElapsedMilliseconds}ms");
                GarbWaitWatch.Restart();
                TurnOnLightByGrabType(grabPoints[grabIndex].grabLights[lightIndex]);
                //等待光源打开完成
                //ThreadHelper.Delay(CameraGrabConfig.TurnOnLightTime, true);
                //触发相机拍照
                CameraTriggerOn(new FrameInfo()
                {
                    uuid = productData.Uuid,
                    code = productData.QrCode,
                    index = grabPoints[grabIndex].Index + 1,
                    IsBlackPatch = false,
                    LightType = grabPoints[grabIndex].grabLights[lightIndex],
                });
                Logout($"CameraTriggerOn完成");
                lastTime = DateTime.Now;
                if (CameraGrabConfig.GlobalGrabMode == CameraGrabConfig.GrabModelEnum.Optimization)
                {
                    ThreadHelper.Delay(CameraGrabConfig.ExposureEndTimeRgb, true);
                    CameraGrabConfig.ExposureSemaphore.Release();
                }
                return PointStepE.GrabWait;
            }
            if (TimeOutCheck())
            {
                return PointStepE.GrabNone;
            }
            else
            {
                return PointStepE.Grabbing;
            } 
        }
        
        /// <summary>
        /// 拍照状态
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepGrabWait()
        {
            //等待拍照完成
            CameraGrabConfig.ExposureSemaphore.WaitOne();
            if (true)
            {
                CameraTriggerOff();
                TurnOffLightByGrabType(GrabLightTypeE.RGBAndWhite);
                if (lightIndex < grabPoints[grabIndex].grabLights.Count - 1)
                {
                    if (true)
                    {
                        Logout($"收到相机取像,点位:{grabIndex},图像:{lightIndex}");
                        lightIndex++;
                        lastTime = DateTime.Now;

                        return PointStepE.Grabbing;
                    }
                }
                else
                {
                    if (grabPoints[grabIndex].grabDlps.Count > 0)
                    {
                        lastTime = DateTime.Now;
                        return PointStepE.GrabDlpGrabbing;
                    }
                    grabIndex++;
                    return PointStepE.GrabGoto;
                }
            }

            if (TimeOutCheck())
            {
                return PointStepE.GrabNone;
            }
            else
            {
                return PointStepE.GrabWait;
            }
        }
        /// <summary>
        /// 光机取像触发
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepDlpGrabbing()
        {
            if (AxisX.IsCheckDone() && AxisY.IsCheckDone())
            {
                IsGrabImageEnd = false;
                camera.SetHardTriggerInfo(new FrameInfo()
                {
                    uuid = productData.Uuid,
                    code = productData.QrCode,
                    index = grabPoints[grabIndex].Index + 1,
                    IsBlackPatch = false,
                    LightType = grabPoints[grabIndex].grabDlps[dlpIndex].LightType,
                    DlpLocationIndex = (int)grabPoints[grabIndex].grabDlps[dlpIndex].DlpIndex,
                    DlpImageIndex = 0
                });

                ImageCount = 1;             //光机图片清0
                //exposureEnd = false;        //曝光清0

                grabWatch.Restart();
                //获取四次拍照锁
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                grabPoints[grabIndex].grabDlps[dlpIndex].DlpTrigger.TurnOn();
                Thread.Sleep(10);
                grabPoints[grabIndex].grabDlps[dlpIndex].DlpTrigger.TurnOff();
                if (CameraGrabConfig.GlobalGrabMode == CameraGrabConfig.GrabModelEnum.Optimization)
                {
                    ThreadHelper.Delay(CameraGrabConfig.ExposureEndTimeDlp,true);
                    CameraGrabConfig.ExposureSemaphore.Release();
                }

                lastTime = DateTime.Now;
                Logout($"触发光机取像,取像点:{grabIndex},图像:{dlpIndex}");
                return PointStepE.GrabDlpWait;
            }

            if (TimeOutCheck())
            {
                return PointStepE.GrabNone;
            }
            else
            {
                return PointStepE.GrabDlpGrabbing;
            }
        }
        /// <summary>
        /// 光机取像等待
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepDlpWait()
        {
            CameraGrabConfig.ExposureSemaphore.WaitOne();
            if (true)
            {
                grabPoints[grabIndex].grabDlps[dlpIndex].DlpTrigger.TurnOff();
                if (dlpIndex < grabPoints[grabIndex].grabDlps.Count - 1)
                {
                    Logout($"收到光机取像,取像点:{grabIndex},图像:{dlpIndex}");
                    //exposureEnd = false;
                    dlpIndex++;
                    lastTime = DateTime.Now;
                    return PointStepE.GrabDlpGrabbing;
                }
                else
                {
                    grabIndex++;
                    return PointStepE.GrabGoto;
                }
            }

            if (TimeOutCheck())
            {
                return PointStepE.GrabNone;
            }
            else
            {
                return PointStepE.GrabDlpWait;
            }
        }
        /// <summary>
        /// 结束状态
        /// </summary>
        /// <returns></returns>
        private PointStepE PointStepGrabFinish()
        {
            ++GrabRoundIndex;
            if (AxisX.IsCheckDone() && AxisY.IsCheckDone())
            {
                Logout("检测取像本次取像结束.");
                if (conveyors.ContainsKey(productData.Station))
                {
                    if (conveyors[productData.Station].WorkMode == CameraWorkModeE.Manual)
                    {
                        conveyors.TryRemove(productData.Station, out var info);
                    }
                }
                
                if (conveyors.Count > 0)
                {
                    return PointStepE.GrabInit;
                }
                else
                {
                    return PointStepE.GrabExit;
                }
            }
            ///新增
            TimeSpan span = DateTime.Now - lastTime;
            if (span.TotalMilliseconds < 1000) //最多只等待一秒
            {
                return  PointStepE.GrabFinish;
            }
            else
            {
                Logout("检测取像本次取像结束.");

                if (conveyors.ContainsKey(productData.Station))
                {
                    if (conveyors[productData.Station].WorkMode == CameraWorkModeE.Manual)
                    {
                        conveyors.TryRemove(productData.Station, out var info);
                    }
                }

                if (conveyors.Count > 0)
                {
                    return PointStepE.GrabInit;
                }
                else
                {
                    return PointStepE.GrabExit;
                }
            }
            ///新增

            //if (TimeOutCheck())
            //{
            //    return PointStepE.GrabNone;
            //}
            //else
            //{
            //    return PointStepE.GrabFinish;
            //}
        }
        /// <summary>
        /// 退出检测模式
        /// </summary>
        /// <returns></returns>
        public PointStepE PointStepExit()
        {
            Logout($"检测取像退出");
            if (pointStep == PointStepE.GrabWait)
            {
                //grabMutex.ReleaseMutex();
            }
            CameraGrabConfig.ExposureSemaphore.Dispose();
            CameraGrabConfig.GrabSemaphore.Dispose();
            CameraTriggerOff();
            AxisX.MoveStop();
            AxisY.MoveStop();
            productData = null;
            grabAllWatch.Stop();
            TurnOffLightByGrabType(GrabLightTypeE.RGBAndWhite);
            TurnOffLightByGrabType(GrabLightTypeE.DLPLight);
            DataCenter.Instance.CameraProductDataClear(config.ModuleKey);
            return PointStepE.GrabNone;
        }
        /// <summary>
        /// 超时检测
        /// </summary>
        private bool TimeOutCheck()
        {
            TimeSpan span = DateTime.Now - lastTime;
            if (span.TotalMilliseconds >= 3000)
            {
                Logout("取像超时.");
                detectTimeOut = 1;
                lastTime = DateTime.Now;
                PointStepExit();
                return true;
            }
            ThreadHelper.Delay(1, true);
            return false;
        }
        /// <summary>
        /// 空闲状态
        /// </summary>
        /// <returns></returns>
        private ModuleTaskStateE TaskStateIdle()
        {
            if (conveyors.Count > 0)
            {
                if (conveyors.ToList().Exists(itm => itm.Value.WorkMode == CameraWorkModeE.Detect))
                {
                    resetTime = DateTime.Now;           
                    resetStep = ResetStepE.GoBase;  //开始检测运动到待板点就可以了
                    pointStep = PointStepE.GrabInit;
                    return ModuleTaskStateE.Resetting;

                    //pointStep = PointStepE.GrabInit;
                    //return ModuleTaskStateE.Running;
                }
                else
                {
                    pointStep = PointStepE.GrabInit;
                    return ModuleTaskStateE.Running;
                }
            }
            else if (IsReseting)
            {
                IsReseting = false;
                resetTime = DateTime.Now;
                resetStep = ResetStepE.Init;
                return ModuleTaskStateE.Resetting;
            }
            else
            {
                ThreadHelper.Delay(1);
                //return ModuleTaskStateE.Running;
                 return ModuleTaskStateE.Idle;
            }
        }
        /// <summary>
        /// 运行状态
        /// </summary>
        private ModuleTaskStateE TaskStateRunning()
        {
            switch (pointStep)
            {
                case PointStepE.GrabInit:
                    pointStep = PointStepGrabInit();
                    break;
                case PointStepE.GrabReady:
                    pointStep = PointStepGrabReady();
                    break;
                case PointStepE.GrabGoto:
                    pointStep = PointStepGrabGoto();
                    break;
                case PointStepE.Grabbing:
                    pointStep = PointStepGrabbing();
                    break;
                case PointStepE.GrabWait:
                    pointStep = PointStepGrabWait();
                    break;
                case PointStepE.GrabDlpGrabbing:
                    pointStep = PointStepDlpGrabbing();
                    break;
                case PointStepE.GrabDlpWait:
                    pointStep = PointStepDlpWait();
                    break;
                case PointStepE.GrabFinish:
                    pointStep = PointStepGrabFinish();
                    break;
                case PointStepE.GrabExit:
                    pointStep = PointStepExit();
                    break;
                default:
                    break;
            }

            if (conveyors.Count == 0 && PointStepE.GrabNone != pointStep)
            {
                pointStep = PointStepExit();
            }

            if (pointStep == PointStepE.GrabNone)
            {
                return ModuleTaskStateE.Idle;
            }
            else
            {
                return ModuleTaskStateE.Running;
            }
        }
        /// <summary>
        /// 错误状态
        /// </summary>
        /// <returns></returns>
        private ModuleTaskStateE TaskStateError()
        {
            if (IsReseting)
            {
                IsReseting = false;
                resetTime = DateTime.Now;
                resetStep = ResetStepE.Init;
                return ModuleTaskStateE.Resetting;
            }
            else
            {
                ThreadHelper.Delay(1);
                return ModuleTaskStateE.Error;
            }
        }
        /// <summary>
        /// 主线程任务
        /// </summary>
        private void MainTaskFunction()
        {
            while (MainLoop)
            {
                try
                {
                    AlarmProcess();
                    TaskStateProcess();
                    //ThreadHelper.Delay(1);
                    
                }
                catch (Exception ex)
                {
                    Logger.Logerr($"{config.Name}{ex}");
                    SetMainTaskState(ModuleTaskStateE.Error);
                }
            }
        }
        /// <summary>
        /// 任务处理
        /// </summary>
        private void TaskStateProcess()
        {
            switch (runTaskStep)
            {
                case ModuleTaskStateE.Idle:
                    #region 空闲状态
                    SetMainTaskState(TaskStateIdle());                 
                    #endregion
                    break;
                case ModuleTaskStateE.Running:
                    #region 执行运行流程
                    SetMainTaskState(TaskStateRunning());
                    #endregion
                    break;
                case ModuleTaskStateE.Error:
                    #region 错误状态
                    SetMainTaskState(TaskStateError());
                    #endregion
                    break;
                case ModuleTaskStateE.Resetting:
                    #region 执行复位流程
                    SetMainTaskState(ResetFunction());
                    #endregion
                    break;
                default:
                    break;
            }
        }
        /// <summary>
        /// 报警处理
        /// </summary>
        private void AlarmProcess()
        {
            alarmDetect.AlarmForeach();
            if ((runTaskStep != ModuleTaskStateE.Resetting && alarmDetect.IsError())
                || AlarmDevice.Instance.IsAlarm())
            {
                SetMainTaskState(ModuleTaskStateE.Error);
            }
        }
        /// <summary>
        /// 地图路径规划
        /// </summary>
        /// <param name="module"></param>
        /// <param name="length"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public int MapPlan(CameraConf conf, ConveyorModuleE conveyor, float startx, float starty)
        {
            if (productData != null && productData.Station == (int)conveyor)
            {
                Logout($"路径规划失败,{conveyor}轨道模组运行中");
                return -1;
            }

            grabPointsDic[conveyor].Clear();
            MapPath map = GetMapPath(conveyor);
            if (config.GrabMode == GrabModeE.Point)
            {
                mapPoint = map.MapPointPlan(conf.Length, conf.Width, startx, starty);
                if (mapPoint.Row == 0 && mapPoint.Column == 0)
                {
                    return -1;
                }

                int i = 0;
                mapPoint.Positions.ForEach(itm =>
                {
                    grabPointsDic[conveyor].Add(new GrabPoint() 
                    {
                        Index = i, X = itm.x, Y = itm.y, grabLights = PointGrablightType(conf.LightType), grabDlps = PointGrabDlp(conf.LightType),
                    });
                    i++;
                });

                conf.pcbAttri.Row = mapPoint.Row;
                conf.pcbAttri.Column = mapPoint.Column;
                conf.StepX = config.Calibration.StepX;
                conf.StepY = config.Calibration.StepY;
            }

            if (config.GrabMode == GrabModeE.Flying)
            {
                mapFlying = map.MapFlyingPlan(conf.Length, conf.Width);
                if (mapFlying.Row == 0 && mapFlying.Column == 0)
                {
                    return -1;
                }

                conf.pcbAttri.Row = mapFlying.Row;
                conf.pcbAttri.Column = mapFlying.Column;
                conf.StepX = config.Calibration.StepX;
                conf.StepY = config.Calibration.StepY;
            }

            return 0;
        }
        /// <summary>
        /// 自动开始
        /// </summary>
        /// <param name="loopFlag"></param>
        public int AutoStart(CameraWorkModeE mode, int conveyorKey)
        {
            if (runTaskStep == ModuleTaskStateE.Error 
                || runTaskStep == ModuleTaskStateE.Pass)
            {
                Logout($"检测启动失败，当前状态:{runTaskStep}");
                return -1;
            }

            if (!conveyors.ContainsKey(conveyorKey))
            {
                if (!conveyors.TryAdd(conveyorKey, new GrabInfo() { WorkMode = mode }))
                {
                    Logout($"检测启动失败，添加拍照信息失败.");
                    return -1;
                }
            }
            else
            {
                conveyors[conveyorKey].WorkMode = mode;
            }

            if (mode == CameraWorkModeE.Detect)
            {
                DataCenter.Instance.SetCameraResetProcess(config.ModuleKey);
            }

            return 0;
        }
        /// <summary>
        /// 自动停止
        /// </summary>
        /// <returns></returns>
        public int AutoStop(int conveyorKey)
        {
            if (conveyors.ContainsKey(conveyorKey))
            {
                if (!conveyors.TryRemove(conveyorKey, out var info))
                {
                    Logout($"检测停止失败.");
                    return -1;
                }
            }

            return 0;
        }
        /// <summary>
        /// 设置指定Index拍照使用光源      -LZC       
        /// </summary>
        /// <param name="tpwGrabIndexs"></param>
        /// <returns></returns> 
        public int SetPosGrabLight(ConveyorModuleE conveyor, List<GrabPointConfig> grabPoints)
        {
            if (!grabPointsDic.ContainsKey(conveyor))
            {
                Logout($"{conveyor}拍照点位集合不存在.");
                return -1;
            }

            if (grabPoints.Count == 0)
            {
                return 0;
            }

            grabPointsDic[conveyor].Clear();
            MapPath map = GetMapPath(conveyor);
            foreach (var itm in grabPoints)
            {
                List<int> indexs = map.MapPointGrabPositionIndex(itm.PosX, itm.PosY, itm.LenX, itm.LenY);
                indexs.ForEach(it =>
                {
                    if (!grabPointsDic[conveyor].Exists(p => p.Index == it))
                    {
                        grabPointsDic[conveyor].Add(new GrabPoint()
                        {
                            Index = it,
                            X = mapPoint.Positions[it].x,
                            Y = mapPoint.Positions[it].y,
                            grabLights = PointGrablightType(itm.LightType),
                            PositionType = itm.PositionType,
                            grabDlps = PointGrabDlp(itm.LightType)
                        });
                    }
                });
            }

            grabPointsDic[conveyor].Sort((p1, p2) =>
            {
                if (p1.Index != p2.Index)
                {
                    return p1.Index.CompareTo(p2.Index);
                }

                return 0;
            });

            return 0;
        }
        /// <summary>
        /// 模块状态
        /// </summary>
        /// <returns></returns>
        public ModuleTaskStateE ModuleTaskState()
        {
            return runTaskStep;
        }
        /// <summary>
        /// 当前Running轨道
        /// </summary>
        /// <returns></returns>
        public int CurrentRunningConveyor()
        {
            if (productData != null)
            {
                return productData.Station;
            }
            else
            {
                return -1;
            }
        }
        /// <summary>
        /// 单拍取像
        /// </summary>
        /// <param name="lightType"></param>
        public void GrabSingleImage(GrabLightTypeE lightType)
        {
            CameraGrabConfig.GrabSemaphore = new Semaphore(8, 8);

            var grabLights = PointGrablightType(lightType);
            var grabDlps = PointGrabDlp(lightType);
            var id = DateTime.Now.ToString("yyyyMMddHHmmssfff");
            grabLights.ForEach(itm =>
            {
                //获取一次拍照锁
                CameraGrabConfig.GrabSemaphore.WaitOne();
                //exposureEnd = false;
                TurnOnLightByGrabType(itm);
                CameraTriggerOn(new FrameInfo()
                {
                    uuid = id,
                    code = "",
                    index = 0,
                    LightType = itm,
                    IsBlackPatch = false
                });
                ThreadHelper.Delay(50, true);
                TurnOffLightByGrabType(itm);
                CameraTriggerOff();
            });

            grabDlps.ForEach(itm =>
            {
                camera.SetHardTriggerInfo(new FrameInfo()
                {
                    uuid = id,
                    code = "",
                    index = 0,
                    LightType = itm.LightType,
                    IsBlackPatch = false,
                    DlpLocationIndex = (int)itm.DlpIndex,
                    DlpImageIndex = 0
                });
                //获取四次拍照锁
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                CameraGrabConfig.GrabSemaphore.WaitOne();
                itm.DlpTrigger.TurnOn();
                ThreadHelper.Delay(200, true);
                itm.DlpTrigger.TurnOff();
            });
        }

        /// <summary>
        /// 运动到基点
        /// </summary>
        /// <returns></returns>
        public int MoveToBasePoint()
        {
            if (AxisX.IsCheckDone() || AxisY.IsCheckDone())
            {
                AxisX.MoveAbs(basePoint.x);
                AxisY.MoveAbs(basePoint.y);
                Logout($"运动到基点");
                ThreadHelper.Delay(1000);
            }
            return 0;
        }

        public void GetState(ref long state)
        {
            state = 0;
            if (camera != null && camera.IsConnected)
            {
                state |= 1;
            }
            if (AxisX != null && AxisX.IsCheckDone())
            {
                state |= (1 << 1);
            }
            if (AxisY != null && AxisY.IsCheckDone())
            {
                state |= (1 << 2);
            }
            if (strobeR != null && strobeR.IsTurnOn())
            {
                state |= (1 << 3);
            }
            if (strobeG != null && strobeG.IsTurnOn())
            {
                state |= (1 << 4);
            }
            if (strobeB != null && strobeB.IsTurnOn())
            {
                state |= (1 << 5);
            }
            if (strobeW != null && strobeW.IsTurnOn())
            {
                state |= (1 << 6);
            }
            if (camTrigger != null && camTrigger.IsTurnOn())
            {
                state |= (1 << 7);
            }
            if (camLeftDlp != null && camLeftDlp.IsTurnOn())
            {
                state |= (1 << 8);
            }
            if (camRightDlp != null && camRightDlp.IsTurnOn())
            {
                state |= (1 << 9);
            }
            if (camFrontDlp != null && camFrontDlp.IsTurnOn())
            {
                state |= (1 << 10);
            }
            if (camBackDlp != null && camBackDlp.IsTurnOn())
            {
                state |= (1 << 11);
            }
        }

        public bool ReadyGrab()
        {
            if (pointStep == PointStepE.GrabReady)
            { 
                return true;
            }
            return false;
        }
        public bool GrabOver()
        {
            if (runTaskStep == ModuleTaskStateE.Idle || runTaskStep == ModuleTaskStateE.Running)
            {
                if(pointStep == PointStepE.GrabReady)
                { 
                    return true;
                }
            }
            return false;
        }
        public UInt32 GrabRoundCount()
        {
            return GrabRoundIndex;
        }
    }
}
